package abio.XasML.rpc
{
	import mx.rpc.AsyncToken;
	import mx.rpc.Responder;
	
	public class commandChain
	{
		static public const SERIES:String='series';
		static public const PARALLEL:String='parallel';
		private var Mode:String=commandChain.PARALLEL;		
		public function commandChain(mode:String=commandChain.PARALLEL){
			this.Mode=mode;
		}
		
		private var chain:Array=new Array();		
		public function add(cmd:command, ...args):void{
			if(this.bProceeding){	throw('rpcChain proceeding');}
			else{	this.chain.push(new commandSet(cmd, args));}
		}
		
		private var bProceeding:Boolean=false;
		public function proceed(callback:Function=null):void{
			if(this.bProceeding){	throw('rpcChain proceeding');}
			else{
				this.bProceeding=true;			

				function _endProceed():void{
					bProceeding=false;
					if(callback!=null){	callback();}
				}
				
				if(this.Mode==commandChain.SERIES){
					function _proceedSeries(seek:int):void{
						if(seek<chain.length){
							var tempFunc:Function=(chain[seek] as commandSet).cmd.execute;
							var result:AsyncToken=tempFunc.apply((chain[seek] as commandSet).cmd, (chain[seek] as commandSet).args);
													
							result.addResponder(new Responder(function RESULT(value:Object):void{
								_proceedSeries(seek+1);
							},function FAULT(info:Object):void{
								throw('commandChain error');
							}));
						}else{	_endProceed();}
					}					
					_proceedSeries(0);
				}else if(this.Mode==commandChain.PARALLEL){
					var resultList:Array=new Array();					
					for each(var cmdSet:commandSet in chain){
						var tempFunc:Function=cmdSet.cmd.execute;
						var result:AsyncToken=tempFunc.apply(cmdSet.cmd, cmdSet.args);	
						resultList.push(result);
											
						result.addResponder(new Responder(function COMPLETE(value:Object):void{
							for each(var tempResult:AsyncToken in resultList){
								if(tempResult.result==undefined){	return;}
							}
							_endProceed();
						},function FAULT(info:Object):void{
							throw('commandChain error');
						}));
					}
				}else{	throw('commandChain error');}
			}
		}
	}
}

import abio.XasML.rpc.command;
import mx.rpc.AsyncToken;

class commandSet
{
	private var Cmd:command=null;
	internal function get cmd():command{	return this.Cmd;}
	private var Args:Array=null;
	internal function get args():Array{	return this.Args;}
	
	public function commandSet(cmd:command, args:Array){
		this.Cmd=cmd;
		this.Args=args;
	}
}
